/*
 * Copyright (c) 2010, Stuart A MacKenzie III,
 *                     Internet Applications Research and Development, LLC.
 *                     All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright notice, this list of
 *      conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright notice, this list of
 *      conditions and the following disclaimer in the documentation and/or other materials
 *      provided with the distribution.
 *
 *   3. Neither the name of Internet Applications Research and Development, LLC nor the names of
 *      its contributors may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package net.iarad.util.csv;

/**
 * TODO: Document this Class
 *
 * @author Stuart A MacKenzie - defconx@gmail.com
 *
 * @version 0.09
 */
public class MsgConstants {

    //-- Quote Styles
	//---------------
	private static class QuoteStyle {
		public final String open, close;
		public QuoteStyle(String quote) { this(quote, quote); }
		public QuoteStyle(String open, String close) {
			this.open = open; this.close = close;
		}
	}

	// -- Messages
	public static class Msg {
		//-- File Not Found
		public static String FileNotFound(String filename) {
			return expandParms(FILE_NOT_FOUND_1, buildParmsArray(filename));
		}
		//-- CVS Read Exception
		public static String CvsReadException(String filename, int lineNumber) {
			return expandParms(CVS_READ_EXCEPTION_2,
					buildParmsArray(filename, Integer.toString(lineNumber)));
		}
		public static String CvsReadException(
				String filename, int lineNumber, int expectedColCount, int foundColCount) {
			return expandParms(CVS_READ_EXCEPTION_4, buildParmsArray(
					filename, Integer.toString(lineNumber),
					Integer.toString(expectedColCount),
					Integer.toString(foundColCount)));
		}
	}

	//-- Immutable
	//----------------
	
	//-- Messages
	//----------------
	protected final static String FILE_NOT_FOUND_1 =
			"Error reading file ${q}${0}${q}";
	
	//-- CSV Read Exception
	protected final static String CVS_READ_EXCEPTION_2 =
			"Error reading file ${q}${0}${q} at line ${q}${1}${q}";
	
	//-- CSV Read Exception
	protected final static String CVS_READ_EXCEPTION_4 =
		"Error reading file ${q}${0}${q} at line ${q}${1}${q}."
		+ "  Expecting ${q}${2}${q} columns, found ${q}${3}${q}.";
	
	//-- Error if last column in line is an escape character.
    protected final static String LAST_COL_IS_ESCAPE_CHAR
    		= "Starting Escape at last position of line";

    //-- Error if last column in line is an Start Quote character.
    protected final static String LAST_COL_IS_START_QUOTE_CHAR
    		= "Starting Quote at last position of line;";

    //-- Error if last column in line is the delimiter character.
    protected final static String LAST_COL_IS_ESCAPE_DELIMITER
    		= "Starting Delimiter at last position of line";


	
	private final static int MIN_PAD = 1;
	
	protected final static int MAX_PAD = 100;
	
	protected final static String QUOTE_TOKEN = "${q}";
	
	protected final static String PARM_START_TOKEN = "${";
	protected final static String PARM_CLOSE_TOKEN = "}";
	protected final static String PARM_INDEX_TOKEN = "i"; // where i = integer < 10 & > 0
	
	
	protected final static String PARM_FORMAT = PARM_START_TOKEN + PARM_INDEX_TOKEN + PARM_CLOSE_TOKEN;
	
	protected final static int PARM_LEN = PARM_FORMAT.length();

	

	//-- Setup static quote styles
	public final static QuoteStyle QS_NONE = new QuoteStyle("");
	
	public final static QuoteStyle QS_SNGL_QUOTE = new QuoteStyle("'");
	
	public final static QuoteStyle QS_SQR_BRKT = new QuoteStyle("[", "]");
	
	public final static QuoteStyle QS_DBL_QUOTE = new QuoteStyle("\"", "\"");
	
	
	//-- Build Parameter Arrays from 1 - 5
	protected final static String[] buildParmsArray(String s1) {
		return new String[] {s1};
	}
	
	protected final static String[] buildParmsArray(String s1, String s2) {
		return new String[] {s1, s2};
	}
	
	protected final static String[] buildParmsArray(String s1, String s2, String s3) {
		return new String[] {s1, s2, s3};
	}
	
	protected final static String[] buildParmsArray(String s1, String s2, String s3, String s4) {
		return new String[] {s1, s2, s3, s4};
	}
	
	protected final static String[] buildParmsArray(String s1, String s2, String s3, String s4, String s5) {
		return new String[] {s1, s2, s3, s4, s5};
	}
	
	//-- Quote - puts current quote style around strings
	protected final static String quote(String s) {
		return currentQuoteStyle.open + s + currentQuoteStyle.close;
	}
		
	/**
	 * Builds a String representation of the variable place holder
	 * based on the index passed in.
	 * <code>${1}</code>
	 * @param i index of the variable to build between 0 and 9 inclusive.
	 * @return String representing the variable of the index passed in.
	 * 	If i < 0 or i > 9 returns <code>${0}</code>
	 */
	public final static String getParm(int i) {
		if(i < 0 || i > 9) { i = 0; }
		return PARM_START_TOKEN + i + PARM_CLOSE_TOKEN;
	}
	
	
	//-- Expand Parameters in Message
	public final static String expandParms(String msg, String[] parms) {
//        System.err.println("msg: " + msg);
//        System.err.println("Parms count: " + parms.length);
        StringBuilder sb = new StringBuilder(msg);

        int start = 0;
        boolean opened = false;
        for (int i = 0; i < parms.length; i++) {
            start = sb.indexOf(getParm(i), start);
//			System.out.println("found - " + getParm(i) + " at '" + start +"'");
            if (start > -1) {
                sb.replace(start, start + PARM_LEN, parms[i]);
            }
        }
        return expandQuotes(sb).toString();
    }
	
	//-- Smart Expand quote variable in Message
	//-- + places opening and closing quotes appropriately.
	private final static String expandQuotes(StringBuilder sb) {
		boolean opened = false;
		int start = sb.indexOf(QUOTE_TOKEN);
		while(start > -1) {
//			System.out.println("found - " + QUOTE_TOKEN + " at '" + start +"'");
			if (opened) {	
				sb.replace(start, start + QUOTE_TOKEN.length(), currentQuoteStyle.close);
			} else {
				sb.replace(start, start + QUOTE_TOKEN.length(), currentQuoteStyle.open);
			}
			opened = !opened;
			start = sb.indexOf(QUOTE_TOKEN, start);
		}
		return sb.toString();
	}


	//--
	//---- Mutable
	//----------------
	public static boolean padInsideQuote = false;
	
	public static QuoteStyle currentQuoteStyle = QS_SQR_BRKT;
	
	public static void setQuoteStyle(QuoteStyle qs) { currentQuoteStyle = qs; }
	
	public final static void main(String[] args) {

		System.out.println(" - " + Msg.FileNotFound("File 1") + " -");
		
		setQuoteStyle(QS_SNGL_QUOTE);
		System.out.println(" - " + Msg.FileNotFound("File 2") + " -");

	}
}
